package com.zzzzzz.gen.crud;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.DefaultResourceLoader;

import com.google.common.base.Joiner;
import com.google.common.io.Files;
import com.zzzzzz.plugins.FreeMarkers;
import com.zzzzzz.utils.mapper.JsonMapper;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class Gen {
	private final static String separator = File.separator;
	private final static String tmplBasePath = "src/main/java/com/zzzzzz/gen/crud/tmpl";
	private final static String configBasePath = "src/main/java/com/zzzzzz/gen/crud/config";
	// settings
	private static String projectPath = null;

	private static void initProjectPath() throws IOException {
		File projectFile = new DefaultResourceLoader().getResource("").getFile();
		while (!new File(projectFile.getPath() + separator + "src" + separator + "main").exists()) {
			projectFile = projectFile.getParentFile();// make sure the project file is the src file's parent
		}
		projectPath = projectFile.getPath();
		logger.info("projectPath: {}", projectPath);
	}

	private static String getPath(String basePath) throws Exception {
		String path = projectPath + separator + StringUtils.replace(basePath, "/", separator);
		return path;
	}

	private static void writeFile(Configuration cfg, String tmplName, Map<String, Object> model, String filePath) throws IOException {
		// 生成 Entity
		Template template = cfg.getTemplate(tmplName);
		String content = FreeMarkers.renderTemplate(template, model);

		File file = new File(filePath).getParentFile();
		if (!file.exists()) {
			file.mkdirs();
		}
		Files.write(content.getBytes(), new File(filePath));
		logger.info("Entity: {}", filePath);
	}

	public static List<Map<String, Object>> getConfigMapList(String configPath) throws IOException {
		List<Map<String, Object>> configMapList = new ArrayList<Map<String, Object>>();
		File configFile = new File(configPath + separator + "shipment" + ".json");
		List<String> configLines = Files.readLines(configFile, Charset.forName("utf-8"));
		String configStr = Joiner.on("").join(configLines);
		logger.debug(configStr);
		
		JsonMapper jsonMapper = new JsonMapper();
		Map<String, Object> configMap = jsonMapper.fromJson(configStr, Map.class);

		configMapList.add(configMap);
		return configMapList;
	}

	public static void main(String[] args) throws Exception {
		initProjectPath();
		String tmplPath = getPath(tmplBasePath);
		String configPath = getPath(configBasePath);

		Configuration cfg = new Configuration();
		cfg.setDirectoryForTemplateLoading(new File(tmplPath));
		cfg.setWhitespaceStripping(true);

		List<Map<String, Object>> configMapList = getConfigMapList(configPath);
		for (Map<String, Object> configMap : configMapList) {
			Object daoConfig = configMap.get("daoConfig");
			String basePath = configMap.get("basePath").toString();
			String projectName = configMap.get("projectName").toString();
			if(daoConfig != null){
				String javaPath = getPath(configMap.get("javaBasePath").toString()+"/"+basePath);
				configMap.put("javaPath", javaPath);
				String classNameCap = StringUtils.capitalize(configMap.get("className").toString());
				configMap.put("ClassName", classNameCap);
				String filePath = javaPath + separator + classNameCap + ".java";
				writeFile(cfg, "entity.ftl", configMap, filePath);
				
				String sqlPath = getPath(configMap.get("sqlPath").toString());
				filePath = sqlPath + separator + configMap.get("className") + ".sql";
				writeFile(cfg, "mysql.ftl", configMap, filePath);
				
				filePath = javaPath + separator + classNameCap + "Dao.java";
				writeFile(cfg, "dao.ftl", configMap, filePath);
				
				filePath = javaPath + separator + classNameCap + "Service.java";
				writeFile(cfg, "service.ftl", configMap, filePath);
				
				filePath = javaPath + separator + classNameCap + "Web.java";
				writeFile(cfg, "controller.ftl", configMap, filePath);
			}
			
			Object jspBasePath = configMap.get("jspBasePath");
			if (jspBasePath != null) {
				String jspPath = getPath(jspBasePath.toString()+"/"+basePath);
				String filePath = jspPath + ".jsp";
				writeFile(cfg, "jsp.ftl", configMap, filePath);
			}

			Object jsBasePath = configMap.get("jsBasePath");
			if (jsBasePath != null) {
				String jsPath = getPath(jsBasePath.toString()+projectName+"/"+basePath);
				String filePath = jsPath + ".js";
				writeFile(cfg, "js.ftl", configMap, filePath);
			}
		}

		logger.info("Generate Success.");
	}

	private static Logger logger = LoggerFactory.getLogger(Gen.class);
}
